<?php
/**
 * This file is part of webman.
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the MIT-LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @author    walkor<walkor@workerman.net>
 * @copyright walkor<walkor@workerman.net>
 * @link      http://www.workerman.net/
 * @license   http://www.opensource.org/licenses/mit-license.php MIT License
 */

use support\Request;
use support\Response;
use support\bootstrap\Translation;
use Webman\App;
use Webman\Config;
use Webman\Route;
use Workerman\Protocols\Http\Session;
use Webman\Exception\ClassNotFoundException;

define('BASE_PATH', realpath(__DIR__ . '/../'));

/**
 * @return string
 */
function base_path()
{
    return BASE_PATH;
}

/**
 * @return string
 */
function app_path()
{
    return BASE_PATH . DIRECTORY_SEPARATOR . 'app';
}

/**
 * @return string
 */
function public_path()
{
    return BASE_PATH . DIRECTORY_SEPARATOR . 'public';
}

/**
 * @return string
 */
function config_path()
{
    return BASE_PATH . DIRECTORY_SEPARATOR . 'config';
}

/**
 * @return string
 */
function runtime_path()
{
    return BASE_PATH . DIRECTORY_SEPARATOR . 'runtime';
}

/**
 * @param int $status
 * @param array $headers
 * @param string $body
 * @return Response
 */
function response($body = '', $status = 200, $headers = array())
{
    return new Response($status, $headers, $body);
}

/**
 * @param $data
 * @param int $options
 * @return Response
 */
function json($data, $options = JSON_UNESCAPED_UNICODE)
{
    return new Response(200, ['Content-Type' => 'application/json'], json_encode($data, $options));
}

if (!function_exists('throw_strack_exception')) {
    /**
     * 抛出Strack异常
     * @param $msg
     * @param int $code
     * @param array $data
     * @throws exception
     */
    function throw_strack_exception($msg, $code = -400000, $data = [])
    {
        $errorData = [
            "code" => $code,
            "msg" => $msg,
            "data" => $data
        ];
        throw new \support\exception\HttpResponseException(json_encode($errorData, JSON_UNESCAPED_UNICODE));
    }
}

if (!function_exists('success_response')) {
    /**
     * 成功返回数据
     * @param string $message
     * @param array $data
     * @param int $status
     * @return array
     */
    function success_response($message = '', $data = [], $status = 0)
    {
        return ["code" => $status, "msg" => $message, "data" => $data];
    }
}

/**
 * @param $xml
 * @return Response
 */
function xml($xml)
{
    if ($xml instanceof SimpleXMLElement) {
        $xml = $xml->asXML();
    }
    return new Response(200, ['Content-Type' => 'text/xml'], $xml);
}

/**
 * @param $data
 * @param string $callback_name
 * @return Response
 */
function jsonp($data, $callback_name = 'callback')
{
    if (!is_scalar($data) && null !== $data) {
        $data = json_encode($data);
    }
    return new Response(200, [], "$callback_name($data)");
}

/**
 * @param $location
 * @param int $status
 * @param array $headers
 * @return Response
 */
function redirect($location, $status = 302, $headers = [])
{
    $response = new Response($status, ['Location' => $location]);
    if (!empty($headers)) {
        $response->withHeaders($headers);
    }
    return $response;
}

/**
 * @return Request
 */
function request()
{
    return App::request();
}

/**
 * @param $key
 * @param null $default
 * @return mixed
 */
function config($key = null, $default = null)
{
    return Config::get($key, $default);
}

/**
 * @param $name
 * @param array $parameters
 * @return string
 */
function route($name, $parameters = [])
{
    $route = Route::getByName($name);
    if (!$route) {
        return '';
    }
    return $route->url($parameters);
}

/**
 * @param null $key
 * @param null $default
 * @return mixed
 */
function session($key = null, $default = null)
{
    $session = request()->session();
    if (null === $key) {
        return $session;
    }
    if (\is_array($key)) {
        $session->put($key);
        return null;
    }
    return $session->get($key, $default);
}

if (!function_exists('env')) {
    /**
     * @param $key
     * @param null $default
     * @return array|bool|false|mixed|string
     */
    function env($key, $default = null)
    {
        $value = getenv($key);

        if ($value === false) {
            return $default;
        }

        switch (strtolower($value)) {
            case 'true':
            case '(true)':
                return true;
            case 'false':
            case '(false)':
                return false;
            case 'empty':
            case '(empty)':
                return '';
            case 'null':
            case '(null)':
                return null;
        }

        if (($valueLength = strlen($value)) > 1 && $value[0] === '"' && $value[$valueLength - 1] === '"') {
            return substr($value, 1, -1);
        }

        return $value;
    }
}

/**
 * @param null|string $id
 * @param array $parameters
 * @param string|null $domain
 * @param string|null $locale
 * @return string
 */
function trans(string $id, array $parameters = [], string $domain = null, string $locale = null)
{
    return Translation::trans($id, $parameters, $domain, $locale);
}

/**
 * @param null|string $locale
 * @return string
 */
function locale(string $locale)
{
    if (!$locale) {
        return Translation::getLocale();
    }
    Translation::setLocale($locale);
}

/**
 * @param $worker
 * @param $class
 */
function worker_bind($worker, $class)
{
    $callback_map = [
        'onConnect',
        'onMessage',
        'onClose',
        'onError',
        'onBufferFull',
        'onBufferDrain',
        'onWorkerStop',
        'onWebSocketConnect'
    ];
    foreach ($callback_map as $name) {
        if (method_exists($class, $name)) {
            $worker->$name = [$class, $name];
        }
    }
    if (method_exists($class, 'onWorkerStart')) {
        call_user_func([$class, 'onWorkerStart'], $worker);
    }
}

/**
 * @return int
 */
function cpu_count()
{
    if (strtolower(PHP_OS) === 'darwin') {
        $count = shell_exec('sysctl -n machdep.cpu.core_count');
    } else {
        $count = shell_exec('nproc');
    }
    $count = (int)$count > 0 ? (int)$count : 4;
    return $count;
}


if (!function_exists('get_format_date')) {
    /**
     * string格式化用户使用语言
     * @param $time
     * @param int $type
     * @param bool $isGantt
     * @return false|string
     */
    function get_format_date($time, $type = 0, $isGantt = false)
    {
        if (!empty($time) && is_numeric($time)) {

            $timestamp = $time + (3600 * 8);

            switch ($type) {
                case 0:
                    if ($isGantt) {
                        $date = gmdate("d-m-Y", $timestamp);
                    } else {
                        $date = gmdate("Y-m-d", $timestamp);
                    }
                    break;
                case 2:
                    $date = gmdate("Y-m-d H:i", $timestamp);
                    break;
                case 1:
                default:
                    $date = gmdate("Y-m-d H:i:s", $timestamp);
                    break;
            }

            return $date;
        } else {
            return '';
        }
    }
}

if (!function_exists('get_current_day_range')) {
    /**
     * 获取当前时间所在天的开始时间与结束时间戳
     * @param $timestamp
     * @return array
     */
    function get_current_day_range($timestamp)
    {
        $ret = array();
        $ret['sdate'] = strtotime(date('Y-m-d', $timestamp));
        $ret['edate'] = $ret['sdate'] + 86399;
        return $ret;
    }
}

if (!function_exists('check_tel_number')) {
    /**
     * 验证电话号码方法
     * @param $number
     * @param string $type
     * @return bool
     */
    function check_tel_number($number, $type = 'phone')
    {
        $regxArr = array(
            'phone' => '/^(\+?86-?)?(19|18|17|16|15|14|13)[0-9]{9}$/',
            'telephone' => '/^(010|02\d{1}|0[3-9]\d{2})-\d{7,9}(-\d+)?$/',
            '400' => '/^400(-\d{3,4}){2}$/',
        );
        if ($type && isset($regxArr[$type])) {
            return preg_match($regxArr[$type], $number) ? true : false;
        }
        foreach ($regxArr as $regx) {
            if (preg_match($regx, $number)) {
                return true;
            }
        }
        return false;
    }
}

if (!function_exists('create_sms_code')) {
    /**
     * 生成短信验证码
     * @param int $length
     * @return int
     */
    function create_sms_code($length = 6)
    {
        $min = pow(10, ($length - 1));
        $max = pow(10, $length) - 1;
        return rand($min, $max);
    }
}
